----------------------------------------------------------------------
-- Bit-serial running sum
-- Stephen West, James Carroll
-- BYU ECEn 620, October 2008
----------------------------------------------------------------------
Library ieee;
	use ieee.std_logic_1164.all;
	use ieee.numeric_std.all;
	
	--latency first lsb comes out word_length*(code_vector_length-1)
	
entity BitSerialSum16 is
	generic(
		word_length:integer:=8;
		code_vector_length:integer:=16
		--final word length = word_length+log2(code_vector_length)
	);
	port(
		clk, lsb_in:in std_logic;
		a_in: in std_logic_vector(code_vector_length-1 downto 0);
			sum_out, lsb_out: out std_logic
	);
end entity;

architecture BitSerialSum16 of BitSerialSum16 is
	type std_logic_vector16x6 is array (code_vector_length-1 downto 0) of std_logic_vector(5 downto 0);
	type unsigned16x6 is array (code_vector_length-1 downto 0) of unsigned(5 downto 0);
	
	signal extended: std_logic_vector16x6;
	signal ext_uns: unsigned16x6;
	signal carry, carry_val:unsigned(4 downto 0):=(others=>'0');
	signal sum:unsigned(5 downto 0);
begin
	ouo: for N in 0 to code_vector_length-1 generate
		extended(N)<="00000"&a_in(N);
		ext_uns(N)<=unsigned(extended(N));
	end generate;
	sum<=ext_uns(0)
		+ext_uns(1)
		+ext_uns(2)
		+ext_uns(3)
		+ext_uns(4)
		+ext_uns(5)
		+ext_uns(6)
		+ext_uns(7)
		+ext_uns(8)
		+ext_uns(9)
		+ext_uns(10)
		+ext_uns(11)
		+ext_uns(12)
		+ext_uns(13)
		+ext_uns(14)
		+ext_uns(15)
		+carry_val;
	carry_val<=(others=>'0') when lsb_in='1'else carry;
	process(clk,sum,lsb_in)
	begin
		if(clk'event and clk='1') then
			carry<=sum(sum'high downto 1);
		end if;
	end process;
	
	sum_out<=std_logic(sum(0));
	lsb_out<=lsb_in;
end architecture;
